package com.chushouya.common.shunfeng;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chushouya.common.config.ShunFengConfig;
import com.chushouya.common.shunfeng.dto.ContactInfo;
import com.chushouya.common.shunfeng.dto.SfCreateOrderDTO;
import com.chushouya.common.shunfeng.dto.ShunfengResponse;
import com.general.framework.core.lang.Dates;
import com.general.framework.core.lang.Jsons;
import com.general.framework.core.lang.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 顺丰快递工具类
 * 整合了订单创建、取消、查询等常用功能
 */
@Component
@Slf4j
public class ShunfengExpressUtil {

    @Resource
    private ShunFengConfig shunFengConfig;

    /**
     * 预约快递下单
     *
     * @param senderInfo      寄件人信息
     * @param cargoName       货物名称
     * @param appointmentTime 预约时间
     * @return 下单结果
     */
    public SfCreateOrderDTO createExpressOrder(ContactInfo senderInfo,
                                             String cargoName, Date appointmentTime) {
        log.info("开始创建顺丰快递订单，货物：{}，预约时间：{}", cargoName, appointmentTime);
        
        try {
            // 生成订单号
            String orderId = generateOrderId();
            String sendStartTm = Dates.format(appointmentTime, "yyyy-MM-dd HH:mm:ss");
            ContactInfo receiverInfo = defaultReceiverInfo();
            // 设置联系人类型
            senderInfo.setContactType(SFContactTypeEnum.SENDER.value());

            // 调用顺丰API
            ShunfengResponse response = expReceCreateOrder(orderId, cargoName, senderInfo, 
                    receiverInfo, sendStartTm, shunFengConfig.getMonthlyCard());
            
            return parseCreateOrderResponse(orderId, response);
            
        } catch (Exception e) {
            log.error("创建顺丰快递订单异常：{}", e.getMessage(), e);
            SfCreateOrderDTO errorResult = new SfCreateOrderDTO();
            errorResult.setErrorMsg("创建订单异常：" + e.getMessage());
            errorResult.setErrorCode("SYSTEM_ERROR");
            return errorResult;
        }
    }

    /**
     * 预约退货
     */
    public SfCreateOrderDTO createReturnExpressOrder(ContactInfo receiverInfo,
                                                   String cargoName, Date appointmentTime) {
        log.info("开始创建顺丰退货订单，货物：{}，预约时间：{}", cargoName, appointmentTime);

        try {
            // 生成订单号
            String orderId = generateOrderId();
            String sendStartTm = Dates.format(appointmentTime, "yyyy-MM-dd HH:mm:ss");
            ContactInfo senderInfo = defaultReceiverInfo();
            // 设置联系人类型
            receiverInfo.setContactType(SFContactTypeEnum.RECEIVER.value());
            senderInfo.setContactType(SFContactTypeEnum.SENDER.value());
            // 调用顺丰API
            ShunfengResponse response = expReceCreateOrder(orderId, cargoName, senderInfo,
                    receiverInfo, sendStartTm, shunFengConfig.getMonthlyCard());

            return parseCreateOrderResponse(orderId, response);

        } catch (Exception e) {
            log.error("创建顺丰退货订单异常：{}", e.getMessage(), e);
            SfCreateOrderDTO errorResult = new SfCreateOrderDTO();
            errorResult.setErrorMsg("创建退货订单异常：" + e.getMessage());
            errorResult.setErrorCode("SYSTEM_ERROR");
            return errorResult;
        }
    }

    /**
     * 取消快递订单
     *
     * @param sfOrderId 顺丰订单号
     * @return 取消结果
     */
    public ShunfengResponse cancelExpressOrder(String sfOrderId) {
        log.info("开始取消顺丰快递订单：{}", sfOrderId);
        
        try {
            ShunfengResponse response = expReceCancelOrder(sfOrderId);
            log.info("取消顺丰订单完成，订单号：{}，结果：{}", sfOrderId, response.getApiResultData());
            return response;
            
        } catch (Exception e) {
            log.error("取消顺丰快递订单异常，订单号：{}，异常：{}", sfOrderId, e.getMessage(), e);
            ShunfengResponse errorResponse = new ShunfengResponse();
            errorResponse.setApiErrorMsg("取消订单异常：" + e.getMessage());
            errorResponse.setApiResultCode("CANCEL_ERROR");
            return errorResponse;
        }
    }

    /**
     * 查询快递订单状态
     *
     * @param sfOrderId 顺丰订单号
     * @return 查询结果
     */
    public ShunfengResponse queryExpressOrder(String sfOrderId) {
        log.info("开始查询顺丰快递订单：{}", sfOrderId);
        
        try {
            ShunfengResponse response = expReceSearchOrderResp(sfOrderId);
            log.info("查询顺丰订单完成，订单号：{}，结果：{}", sfOrderId, response.getApiResultData());
            return response;
            
        } catch (Exception e) {
            log.error("查询顺丰快递订单异常，订单号：{}，异常：{}", sfOrderId, e.getMessage(), e);
            ShunfengResponse errorResponse = new ShunfengResponse();
            errorResponse.setApiErrorMsg("查询订单异常：" + e.getMessage());
            errorResponse.setApiResultCode("QUERY_ERROR");
            return errorResponse;
        }
    }

    /**
     * 创建默认寄件人信息（使用配置中的信息）
     *
     * @return 寄件人信息
     */
    public ContactInfo defaultReceiverInfo() {
        ContactInfo senderInfo = new ContactInfo();
        senderInfo.setContactType(SFContactTypeEnum.RECEIVER.value());
        senderInfo.setContact(shunFengConfig.getContact());
        senderInfo.setMobile(shunFengConfig.getMobile());
        senderInfo.setProvince(shunFengConfig.getProvince());
        senderInfo.setCity(shunFengConfig.getCity());
        senderInfo.setCounty(shunFengConfig.getCounty());
        senderInfo.setAddress(shunFengConfig.getAddress());
        return senderInfo;
    }

    /**
     * 生成订单号
     */
    private String generateOrderId() {
        return Strings.format("CSY{}", RandomStringUtils.randomNumeric(10));
    }

    /**
     * 解析创建订单响应
     */
    private SfCreateOrderDTO parseCreateOrderResponse(String orderId, ShunfengResponse response) {
        SfCreateOrderDTO result = new SfCreateOrderDTO();
        result.setSfOrderId(orderId);

        if (Objects.isNull(response.getApiResultData())) {
            result.setErrorMsg(response.getApiErrorMsg());
            result.setErrorCode(response.getApiResultCode());
            return result;
        }

        if (response.isSuccess()) {
            JSONObject json = JSON.parseObject(response.getApiResultData());

            // 判断业务是否成功
            if (!json.getBoolean("success")) {
                result.setErrorMsg(json.getString("errorMsg"));
                result.setErrorCode(json.getString("errorCode"));
            } else {
                // 获取快递单号
                JSONObject msgData = json.getJSONObject("msgData");
                String waybillNo = "";
                if (Objects.nonNull(msgData.getJSONArray("waybillNoInfoList")) 
                        && msgData.getJSONArray("waybillNoInfoList").size() > 0) {
                    waybillNo = msgData.getJSONArray("waybillNoInfoList")
                            .getJSONObject(0).getString("waybillNo");
                }
                result.setExpressNo(waybillNo);
                log.info("顺丰下单成功，订单号：{}，快递单号：{}", orderId, waybillNo);
            }
        } else {
            result.setErrorMsg("API调用失败：" + response.getApiErrorMsg());
            result.setErrorCode(response.getApiResultCode());
        }

        return result;
    }

    // ==================== 以下为底层API调用方法 ====================

    /**
     * 顺丰下单API
     */
    private ShunfengResponse expReceCreateOrder(String orderId, String cargoName, ContactInfo src, 
                                              ContactInfo target, String sendStartTm, String monthlyCard) {
        JSONObject msg = new JSONObject();
        msg.put("language", "zh-CN");
        msg.put("orderId", orderId);
        msg.put("sendStartTm", sendStartTm);

        // 托寄物信息
        JSONArray cargoDetails = new JSONArray();
        JSONObject cargoDetail = new JSONObject();
        cargoDetail.put("name", cargoName);
        cargoDetail.put("unit", "台");
        cargoDetail.put("count", 1);
        cargoDetails.add(cargoDetail);
        msg.put("cargoDetails", cargoDetails);

        // 收寄双方信息
        JSONArray contactInfoList = new JSONArray();
        contactInfoList.add(src);
        contactInfoList.add(target);
        msg.put("contactInfoList", contactInfoList);

        // 支付方式 1:寄方付 2:收方付 3:第三方付
        msg.put("payMethod", 2);
        // 月结卡号
        msg.put("monthlyCard", monthlyCard);
        // 快件产品类别 1:特快 2:标快
        msg.put("expressTypeId", 2);
        // 是否返回路由标签
        msg.put("isReturnRoutelabel", 1);
        msg.put("isDocall", 1);
        msg.put("parcelQty", 1);

        String response = commonRequest(shunFengConfig.getServerUrl(), 
                buildBodyForms("EXP_RECE_CREATE_ORDER", msg.toString()));
        return JSON.parseObject(response, ShunfengResponse.class);
    }

    /**
     * 顺丰取消订单API
     */
    private ShunfengResponse expReceCancelOrder(String orderId) {
        JSONObject msg = new JSONObject();
        msg.put("orderId", orderId);
        msg.put("dealType", 2);
        String response = commonRequest(shunFengConfig.getServerUrl(), 
                buildBodyForms("EXP_RECE_UPDATE_ORDER", msg.toString()));
        return JSON.parseObject(response, ShunfengResponse.class);
    }

    /**
     * 顺丰查询订单API
     */
    private ShunfengResponse expReceSearchOrderResp(String orderId) {
        JSONObject msg = new JSONObject();
        msg.put("orderId", orderId);
        String response = commonRequest(shunFengConfig.getServerUrl(), 
                buildBodyForms("EXP_RECE_SEARCH_ORDER_RESP", msg.toString()));
        return JSON.parseObject(response, ShunfengResponse.class);
    }

    /**
     * 公共请求方法
     */
    private String commonRequest(String uri, Map<String, String> bodyForms) {
        log.info("请求地址: {}, 请求参数: {}", uri, Jsons.toJsonString(bodyForms));
        try {
            String result = SfHttpClientUtil.post(uri, bodyForms);
            log.info("请求结果: {}", result);
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("顺丰API请求异常：{}", e.getMessage(), e);
            throw new RuntimeException("顺丰API请求异常", e);
        }
    }

    /**
     * 构建请求表单
     */
    private Map<String, String> buildBodyForms(String serviceCode, String msgData) {
        String timestamp = String.valueOf(System.currentTimeMillis());
        Map<String, String> hasMap = new HashMap<>();
        hasMap.put("partnerID", shunFengConfig.getCustomer());
        hasMap.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        hasMap.put("serviceCode", serviceCode);
        hasMap.put("timestamp", timestamp);
        hasMap.put("msgData", msgData);
        hasMap.put("msgDigest", buildMsgDigest(msgData, timestamp));

        return hasMap;
    }

    /**
     * 构建消息摘要
     */
    private String buildMsgDigest(String msgData, String timestamp) {
        try {
            String content = URLEncoder.encode(msgData + timestamp + shunFengConfig.getKey(), "utf-8");
            return Base64.encodeBase64String(DigestUtils.md5(content));
        } catch (UnsupportedEncodingException e) {
            log.error("构建消息摘要异常：{}", e.getMessage(), e);
            throw new RuntimeException("构建消息摘要异常", e);
        }
    }
}
